home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-06-01 | 7.6 KB | 215 lines | [TEXT/GEOL] |
- Item 5722888 26-May-90 15:16PDT
-
- From: MADA2 MacApp Dev Assoc, Curtis Faith,IVC
-
- To: CFI France - Dev, CFI Paris 11,IDV
-
- cc: MACAPP.TECH$ MacApp Technical
-
- Sub: Re: Object Style (Long!)
-
- Nico,
-
- How is life treating you after the WWDC?
-
- I just finished compiling the links for the July Framework's issue and I ran
- across a link that you sent asking about Object Programming style, in your
- words, an "ethical question about OOP."
-
- I just HAD to reply to this link as I feel you brought out an EXTREMELY
- IMPORTANT issue, one that deserves far more response than the one link you
- message received.
-
- I will repeat the discussion here since it was quite some time ago that you
- sent the original:
-
- ________________
- 4/20/9
- CFI France - Dev, CFI Paris 11,IDV
-
-
- Hi !
-
- A class TmyDocument, with methods like
-
- TMyDocument.GiveMeNewMind:TMindObject;
-
- And a class TGame :
- TGame = OBJECT(TObject)
- fMindDocument : TMindDocument;
- (...)
-
- TGame.DoGame;
- (...)
- END;
-
- In the TGame.DoGame method, I need to get a new TMindObject. The question
- is:
- should I write a method TGame.GiveMeNewMind : TmindObject, which only purpose
- would be :
-
- FUNCTION TGame.GiveMeNewMind : TMindObject
- BEGIN
- GiveMeNewMind := fMindDocument.GiveMeNewMind;
- END;
- And in the method TGame.DoGame (and others), I would only see:
- myVar := GiveMeNewMind;
-
- Or just call fMindDocument.GiveMeNewMind from TGame.DoGame ?
-
- This example could seem a little stupid, since it's with a simple function
- call, but I have the same kind of calls with multiple indirections, like
- fGame.fMindDocument.Dothis...
-
- What do you usually do in this type of case?
-
- Nico...
- ______________
- Bob Hablutzel replied:
- ______________
- 4/20/9
- HABLUTZEL Hablutzel, Bob
-
- >> Questions about multiple indirections:
- >>
- >> What do you usually do in this type of case?
-
-
- Personally, I tend to multiple indirect as much as possible. It makes for a (to
- me) more logical program design, hence a more usable program design, hence a
- more (if you'll excuse the expression) programmable program.
-
- Bob
- _______________
-
- Nico,
-
- I must state at the onset that I strongly disagree with Bob.
-
- There are 3 levels of OP style here:
-
- 1) You bring up the first level in the statement:
- "This example could seem a little stupid, since it's with a simple function
- call, but I have the same kind of calls with multiple indirections, like
- fGame.fMindDocument.Dothis..."
-
- Is it good style to use multiple indirections, in a sense accessing the fields
- of objects other than SELF?
-
- 2) Is it good style to access methods of other objects directly everywhere or
- should one define one specific place for this to take place. This corresponds
- to asking whether using:
-
- SELF.GiveMeNewMind; is better than
-
- SELF.fMindDocument.GiveMeNewMind; or SELF.GetMindDocument.GiveMeNewMind;
-
- 3) Is is good style to access one's own fields directly or should this be done
- through "Accessor Methods". Accessor methods are essentially functions that
- return the fields of SELF. These usually take the form of Get's and Set's,
- thus instead of accessing fMindDocument.GiveMeNewMind one would use:
- GetMindDocument.GiveMeNewMind.
-
- How do I begin? Hmmm!
-
- First let me preface by stating that Object Programming should be more than
- just programming with Objects.
-
- I always think of good objects being like people in a corporation. It is far
- better for a manager to be able to delegate tasks to his subordinates. This
- delegation should be limited to telling them what one wants done. It should
- not include telling them how to do what one wants done.
-
- Thus in Object Programming, the less one object knows about the other objects
- it deals with the better. This is always true, I have sometimes fooled myself
- into thinking that I was dealing with a special case that was an exception, I
- was always sorry!
-
- The idea is that you can make major implementation changes in one area of an
- application without affecting another area.
-
- 1) In you example:
- fGame.fMindDocument.Dothis..."
-
- You are in effect hard wiring several pieces of information:
-
- a) This object has an associated object of type TGame.
- b) This TGame is referenced in a field of this object fGame.
- c) TGame has an associated object of type TMindDocument.
- d) This TMindDocument is referenced in a field of the TGame object
- fMindDocument.
- e) TMindDocument has a method DoThis that performs the desired action.
-
- If any of the above ceases to be true you are going to have a problem.
-
- I therefore state that it is always BAD to access fields of object other than
- SELF. NEVER EVER do this! You will be far happier if you don't. Only use
- methods of objects other than self. In fact with some Object Languages like
- C++ it is possible for the designer of an object Class to make it impossible to
- directly access fields. This is a very useful feature as it forces one to use
- proper Object Programming technique.
-
- It is unfortunately not always easy to implement this strategy with Object
- Pascal. What happens when you want to find out how many Rows are in an
- associated TTextListView. One can't simple ask the TTextListView object "How
- many rows do you have?", since TTextListViews do not have a GetNumberOfRows
- method.
-
- A reasonable solution in this case is to subclass TTextListView to provide the
- necessary method GetNumberOfRows and then use the subclass's method. This is a
- bit of a pain and it always annoys me a bit to have to do this, but it is
- worthwhile. If you are using the method GetNumberOfRows and MacApp 2.1 changes
- the way rows are represented you will not have a problem. You will only have
- to change the one Method in the subclass to reflect the necessary changes in
- the TTextListView implementation. If you are accessing
- fTextListView.fNumOfRows directly you will have to change this everywhere it
- occurs.
-
- If one follows the above advice one will never have multiple indirection.
-
- 2) I submit that SELF.GiveMeNewMind; is ALWAYS better than
-
- SELF.fMindDocument.GiveMeNewMind, as it puts all the knowledge that:
-
- a) There is an associated TMindDocument
- b) It is referenced by the SELF.fMindDocument field, and
- c) It has a GiveMeNewMindField.
-
- in one location. This is less of a hard and fast rule as issue number one but
- it is valid nonetheless.
-
- 3) This is a further refinement of the principle of isolation of knowledge. It
- is better to always use Accessor methods. This is even less hard and fast but
- still remains true.
-
- Here are a couple of rules of thumb that I use in Object Design:
-
- The general concepts are:
-
- 1) Keep knowledge of other objects to an absolute minimum.
- 2) Keep knowledge in isolated pockets, thus if one needs to know anything about
- another object, keep this knowledge in one place.
-
- Which become rules:
- 1) Never access fields of other objects.
- 2) If one is going to do something like:
- GetMindDocument.GiveMeNewMind more than once put it in a new method of SELF
- and only use this.
- 3) Always use Gets and Sets, the only reference to fMindDocument should be in
- the Function GetMindDocument.
- 4) Try very hard not to have more than one "." in a given line. Thus even
- GetGame.GetMindDocument.GiveMeNewMind would be considered a minor sin. It
- would be better to define a method of TGame that directly returned a NewMind.
-
- Some might claim that you will lose too much performance if you use these
- rules. I have not found this to be the case. It is amazing how much a Mac can
- do in a millisecond.
-
- Having exhausted the energy in my fingers,
-
- I remain,
-
- Curtis
-
-
-